home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Pager / Common.php next >
PHP Script  |  2004-10-01  |  33KB  |  1,143 lines

  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2002-2003, Richard Heyes, Lorenzo Alberton              |
  4. // | All rights reserved.                                                  |
  5. // |                                                                       |
  6. // | Redistribution and use in source and binary forms, with or without    |
  7. // | modification, are permitted provided that the following conditions    |
  8. // | are met:                                                              |
  9. // |                                                                       |
  10. // | o Redistributions of source code must retain the above copyright      |
  11. // |   notice, this list of conditions and the following disclaimer.       |
  12. // | o Redistributions in binary form must reproduce the above copyright   |
  13. // |   notice, this list of conditions and the following disclaimer in the |
  14. // |   documentation and/or other materials provided with the distribution.|
  15. // | o The names of the authors may not be used to endorse or promote      |
  16. // |   products derived from this software without specific prior written  |
  17. // |   permission.                                                         |
  18. // |                                                                       |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
  30. // |                                                                       |
  31. // +-----------------------------------------------------------------------+
  32. // | Authors: Richard Heyes <richard@phpguru.org>                          |
  33. // |          Lorenzo Alberton <l.alberton at quipo.it>                    |
  34. // +-----------------------------------------------------------------------+
  35. //
  36. // $Id: Common.php,v 1.18 2004/08/17 14:45:57 quipo Exp $
  37.  
  38. /**
  39.  * File Common.php
  40.  *
  41.  * @package Pager
  42.  */
  43. /**
  44.  * Two constants used to guess the path- and file-name of the page
  45.  * when the user doesn't set any pther value
  46.  */
  47. define('CURRENT_FILENAME', basename($_SERVER['PHP_SELF']));
  48. define('CURRENT_PATHNAME', str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])));
  49. /**
  50.  * Error codes
  51.  */
  52. define('PAGER_OK',                     0);
  53. define('ERROR_PAGER',                 -1);
  54. define('ERROR_PAGER_INVALID',         -2);
  55. define('ERROR_PAGER_NOT_IMPLEMENTED', -3);
  56. /**
  57.  * Pager_Common - Common base class for [Sliding|Jumping] Window Pager
  58.  *
  59.  * Usage examples can be found in the doc provided
  60.  *
  61.  * @author Richard Heyes <richard@phpguru.org>,
  62.  * @author Lorenzo Alberton <l.alberton at quipo.it>
  63.  * @version  $Id: Common.php,v 1.18 2004/08/17 14:45:57 quipo Exp $
  64.  * @package Pager
  65.  */
  66. class Pager_Common
  67. {
  68.  
  69.     // {{{ private class vars
  70.  
  71.     /**
  72.      * @var integer number of items
  73.      * @access private
  74.      */
  75.     var $_totalItems;
  76.  
  77.     /**
  78.      * @var integer number of items per page
  79.      * @access private
  80.      */
  81.     var $_perPage     = 10;
  82.  
  83.     /**
  84.      * @var integer number of page links for each window
  85.      * @access private
  86.      */
  87.     var $_delta       = 10;
  88.  
  89.     /**
  90.      * @var integer current page number
  91.      * @access private
  92.      */
  93.     var $_currentPage = 1;
  94.  
  95.     /**
  96.      * @var string CSS class for links
  97.      * @access private
  98.      */
  99.     var $_linkClass   = '';
  100.  
  101.     /**
  102.      * @var string wrapper for CSS class name
  103.      * @access private
  104.      */
  105.     var $_classString = '';
  106.  
  107.     /**
  108.      * @var string path name
  109.      * @access private
  110.      */
  111.     var $_path        = CURRENT_PATHNAME;
  112.  
  113.     /**
  114.      * @var string file name
  115.      * @access private
  116.      */
  117.     var $_fileName    = CURRENT_FILENAME;
  118.  
  119.     /**
  120.      * @var boolean you have to use FALSE with mod_rewrite
  121.      * @access private
  122.      */
  123.     var $_append      = true;
  124.  
  125.     /**
  126.      * @var string name of the querystring var for pageID
  127.      * @access private
  128.      */
  129.     var $_urlVar      = 'pageID';
  130.  
  131.     /**
  132.      * @var string name of the url without the pageID number
  133.      * @access private
  134.      */
  135.     var $_url         = '';
  136.  
  137.     /**
  138.      * @var array additional URL vars
  139.      * @access private
  140.      */
  141.     var $_extraVars   = array();
  142.  
  143.     /**
  144.      * @var boolean TRUE => expanded mode (for Pager_Sliding)
  145.      * @access private
  146.      */
  147.     var $_expanded    = true;
  148.  
  149.     /**
  150.      * @var string alt text for "previous page"
  151.      * @access private
  152.      */
  153.     var $_altPrev     = 'previous page';
  154.  
  155.     /**
  156.      * @var string alt text for "next page"
  157.      * @access private
  158.      */
  159.     var $_altNext     = 'next page';
  160.  
  161.     /**
  162.      * @var string alt text for "page"
  163.      * @access private
  164.      */
  165.     var $_altPage     = 'page';
  166.  
  167.     /**
  168.      * @var string image/text to use as "prev" link
  169.      * @access private
  170.      */
  171.     var $_prevImg     = '<< Back';
  172.  
  173.     /**
  174.      * @var string image/text to use as "next" link
  175.      * @access private
  176.      */
  177.     var $_nextImg     = 'Next >>';
  178.  
  179.     /**
  180.      * @var string link separator
  181.      * @access private
  182.      */
  183.     var $_separator   = '';
  184.  
  185.     /**
  186.      * @var integer number of spaces before separator
  187.      * @access private
  188.      */
  189.     var $_spacesBeforeSeparator = 0;
  190.  
  191.     /**
  192.      * @var integer number of spaces after separator
  193.      * @access private
  194.      */
  195.     var $_spacesAfterSeparator  = 1;
  196.  
  197.     /**
  198.      * @var string CSS class name for current page link
  199.      * @access private
  200.      */
  201.     var $_curPageLinkClassName  = '';
  202.  
  203.     /**
  204.      * @var string Text before current page link
  205.      * @access private
  206.      */
  207.     var $_curPageSpanPre        = '';
  208.  
  209.     /**
  210.      * @var string Text after current page link
  211.      * @access private
  212.      */
  213.     var $_curPageSpanPost       = '';
  214.  
  215.     /**
  216.      * @var string Text before first page link
  217.      * @access private
  218.      */
  219.     var $_firstPagePre  = '[';
  220.  
  221.     /**
  222.      * @var string Text to be used for first page link
  223.      * @access private
  224.      */
  225.     var $_firstPageText = '';
  226.  
  227.     /**
  228.      * @var string Text after first page link
  229.      * @access private
  230.      */
  231.     var $_firstPagePost = ']';
  232.  
  233.     /**
  234.      * @var string Text before last page link
  235.      * @access private
  236.      */
  237.     var $_lastPagePre   = '[';
  238.  
  239.     /**
  240.      * @var string Text to be used for last page link
  241.      * @access private
  242.      */
  243.     var $_lastPageText  = '';
  244.  
  245.     /**
  246.      * @var string Text after last page link
  247.      * @access private
  248.      */
  249.     var $_lastPagePost  = ']';
  250.  
  251.     /**
  252.      * @var string Will contain the HTML code for the spaces
  253.      * @access private
  254.      */
  255.     var $_spacesBefore  = '';
  256.  
  257.     /**
  258.      * @var string Will contain the HTML code for the spaces
  259.      * @access private
  260.      */
  261.     var $_spacesAfter   = '';
  262.  
  263.     /**
  264.      * @var string $_firstLinkTitle
  265.      * @access private
  266.      */
  267.     var $_firstLinkTitle = 'first page';
  268.  
  269.     /**
  270.      * @var string $_nextLinkTitle
  271.      * @access private
  272.      */
  273.     var $_nextLinkTitle = 'next page';
  274.  
  275.     /**
  276.      * @var string $_prevLinkTitle
  277.      * @access private
  278.      */
  279.     var $_prevLinkTitle = 'previous page';
  280.  
  281.     /**
  282.      * @var string $_lastLinkTitle
  283.      * @access private
  284.      */
  285.     var $_lastLinkTitle = 'last page';
  286.  
  287.     /**
  288.      * @var string Text to be used for the 'show all' option in the select box
  289.      * @access private
  290.      */
  291.     var $_showAllText   = '';
  292.  
  293.     /**
  294.      * @var array data to be paged
  295.      * @access private
  296.      */
  297.     var $_itemData      = null;
  298.  
  299.     /**
  300.      * @var boolean If TRUE and there's only one page, links aren't shown
  301.      * @access private
  302.      */
  303.     var $_clearIfVoid   = true;
  304.  
  305.     /**
  306.      * @var boolean Use session for storing the number of items per page
  307.      * @access private
  308.      */
  309.     var $_useSessions   = false;
  310.  
  311.     /**
  312.      * @var boolean Close the session when finished reading/writing data
  313.      * @access private
  314.      */
  315.     var $_closeSession  = false;
  316.  
  317.     /**
  318.      * @var string name of the session var for number of items per page
  319.      * @access private
  320.      */
  321.     var $_sessionVar    = 'setPerPage';
  322.  
  323.     /**
  324.      * Pear error mode (when raiseError is called)
  325.      * (see PEAR doc)
  326.      *
  327.      * @var int $_pearErrorMode
  328.      * @access private
  329.      */
  330.     var $_pearErrorMode = null;
  331.  
  332.     // }}}
  333.     // {{{ public vars
  334.  
  335.     /**
  336.      * @var string Complete set of links
  337.      * @access public
  338.      */
  339.     var $links = '';
  340.  
  341.     /**
  342.      * @var string Complete set of link tags
  343.      * @access public
  344.      */
  345.     var $linkTags = '';
  346.  
  347.     /**
  348.      * @var array Array with a key => value pair representing
  349.      *            page# => bool value (true if key==currentPageNumber).
  350.      *            can be used for extreme customization.
  351.      * @access public
  352.      */
  353.     var $range = array();
  354.  
  355.     // }}}
  356.     // {{{ getPageData()
  357.  
  358.     /**
  359.      * Returns an array of current pages data
  360.      *
  361.      * @param $pageID Desired page ID (optional)
  362.      * @return array Page data
  363.      * @access public
  364.      */
  365.     function getPageData($pageID = null)
  366.     {
  367.         $pageID = empty($pageID) ? $this->_currentPage : $pageID;
  368.  
  369.  
  370.         if (!isset($this->_pageData)) {
  371.             $this->_generatePageData();
  372.         }
  373.  
  374.         if (!empty($this->_pageData[$pageID])) {
  375.             return $this->_pageData[$pageID];
  376.         }
  377.         return false;
  378.     }
  379.  
  380.     // }}}
  381.     // {{{ getPageIdByOffset()
  382.  
  383.     /**
  384.      * Returns pageID for given offset
  385.      *
  386.      * @param $index Offset to get pageID for
  387.      * @return int PageID for given offset
  388.      */
  389.     function getPageIdByOffset($index)
  390.     {
  391.         $msg = '<b>PEAR::Pager Error:</b>'
  392.               .' function "getPageIdByOffset()" not implemented.';
  393.         return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  394.     }
  395.  
  396.     // }}}
  397.     // {{{ getOffsetByPageId()
  398.  
  399.     /**
  400.      * Returns offsets for given pageID. Eg, if you
  401.      * pass it pageID one and your perPage limit is 10
  402.      * it will return (1, 10). PageID of 2 would
  403.      * give you (11, 20).
  404.      *
  405.      * @param integer PageID to get offsets for
  406.      * @return array  First and last offsets
  407.      * @access public
  408.      */
  409.     function getOffsetByPageId($pageid = null)
  410.     {
  411.         $pageid = isset($pageid) ? $pageid : $this->_currentPage;
  412.         if (!isset($this->_pageData)) {
  413.             $this->_generatePageData();
  414.         }
  415.  
  416.         if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
  417.             return array(
  418.                         max(($this->_perPage * ($pageid - 1)) + 1, 1),
  419.                         min($this->_totalItems, $this->_perPage * $pageid)
  420.                    );
  421.         } else {
  422.             return array(0, 0);
  423.         }
  424.     }
  425.  
  426.     // }}}
  427.     // {{{ getPageRangeByPageId()
  428.  
  429.     /**
  430.      * @param integer PageID to get offsets for
  431.      * @return array  First and last offsets
  432.      */
  433.     function getPageRangeByPageId($pageID)
  434.     {
  435.         $msg = '<b>PEAR::Pager Error:</b>'
  436.               .' function "getPageRangeByPageId()" not implemented.';
  437.         return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  438.     }
  439.  
  440.     // }}}
  441.     // {{{ getLinks()
  442.  
  443.     /**
  444.      * Returns back/next/first/last and page links,
  445.      * both as ordered and associative array.
  446.      *
  447.      * NB: in original PEAR::Pager this method accepted two parameters,
  448.      * $back_html and $next_html. Now the only parameter accepted is
  449.      * an integer ($pageID), since the html text for prev/next links can
  450.      * be set in the factory. If a second parameter is provided, then
  451.      * the method act as it previously did. This hack was done to mantain
  452.      * backward compatibility only.
  453.      *
  454.      * @param integer $pageID Optional pageID. If specified, links
  455.      *                for that page are provided instead of current one.  [ADDED IN NEW PAGER VERSION]
  456.      * @param  string $next_html HTML to put inside the next link [deprecated: use the factory instead]
  457.      * @return array back/next/first/last and page links
  458.      */
  459.     function getLinks($pageID=null, $next_html='')
  460.     {
  461.         $msg = '<b>PEAR::Pager Error:</b>'
  462.               .' function "getLinks()" not implemented.';
  463.         return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  464.     }
  465.  
  466.     // }}}
  467.     // {{{ getCurrentPageID()
  468.  
  469.     /**
  470.      * Returns ID of current page
  471.      *
  472.      * @return integer ID of current page
  473.      */
  474.     function getCurrentPageID()
  475.     {
  476.         return $this->_currentPage;
  477.     }
  478.  
  479.     // }}}
  480.     // {{{ getNextPageID()
  481.  
  482.     /**
  483.      * Returns next page ID. If current page is last page
  484.      * this function returns FALSE
  485.      *
  486.      * @return mixed Next page ID
  487.      */
  488.     function getNextPageID()
  489.     {
  490.         return ($this->getCurrentPageID() == $this->numPages() ? false : $this->getCurrentPageID() + 1);
  491.     }
  492.  
  493.     // }}}
  494.     // {{{ getPreviousPageID()
  495.  
  496.     /**
  497.      * Returns previous page ID. If current page is first page
  498.      * this function returns FALSE
  499.      *
  500.      * @return mixed Previous pages' ID
  501.      */
  502.     function getPreviousPageID()
  503.     {
  504.         return $this->isFirstPage() ? false : $this->getCurrentPageID() - 1;
  505.     }
  506.  
  507.     // }}}
  508.     // {{{ numItems()
  509.  
  510.     /**
  511.      * Returns number of items
  512.      *
  513.      * @return int Number of items
  514.      */
  515.     function numItems()
  516.     {
  517.         return $this->_totalItems;
  518.     }
  519.  
  520.     // }}}
  521.     // {{{ numPages()
  522.  
  523.     /**
  524.      * Returns number of pages
  525.      *
  526.      * @return int Number of pages
  527.      */
  528.     function numPages()
  529.     {
  530.         return (int)$this->_totalPages;
  531.     }
  532.  
  533.     // }}}
  534.     // {{{ isFirstPage()
  535.  
  536.     /**
  537.      * Returns whether current page is first page
  538.      *
  539.      * @return bool First page or not
  540.      */
  541.     function isFirstPage()
  542.     {
  543.         return ($this->_currentPage < 2);
  544.     }
  545.  
  546.     // }}}
  547.     // {{{ isLastPage()
  548.  
  549.     /**
  550.      * Returns whether current page is last page
  551.      *
  552.      * @return bool Last page or not
  553.      */
  554.     function isLastPage()
  555.     {
  556.         return ($this->_currentPage == $this->_totalPages);
  557.     }
  558.  
  559.     // }}}
  560.     // {{{ isLastPageComplete()
  561.  
  562.     /**
  563.      * Returns whether last page is complete
  564.      *
  565.      * @return bool Last age complete or not
  566.      */
  567.     function isLastPageComplete()
  568.     {
  569.         return !($this->_totalItems % $this->_perPage);
  570.     }
  571.  
  572.     // }}}
  573.     // {{{ _generatePageData()
  574.  
  575.     /**
  576.      * Calculates all page data
  577.      * @access private
  578.      */
  579.     function _generatePageData()
  580.     {
  581.         // Been supplied an array of data?
  582.         if (!is_null($this->_itemData)) {
  583.             $this->_totalItems = count($this->_itemData);
  584.         }
  585.         $this->_totalPages = ceil((float)$this->_totalItems / (float)$this->_perPage);
  586.         $i = 1;
  587.         if (!empty($this->_itemData)) {
  588.             foreach ($this->_itemData as $key => $value) {
  589.                 $this->_pageData[$i][$key] = $value;
  590.                 if (count($this->_pageData[$i]) >= $this->_perPage) {
  591.                     $i++;
  592.                 }
  593.             }
  594.         } else {
  595.             $this->_pageData = array();
  596.         }
  597.  
  598.         //prevent URL modification
  599.         $this->_currentPage = min($this->_currentPage, $this->_totalPages);
  600.     }
  601.  
  602.     // }}}
  603.     // {{{ _getLinksUrl()
  604.  
  605.     /**
  606.      * Returns the correct link for the back/pages/next links
  607.      *
  608.      * @return string Url
  609.      * @access private
  610.      */
  611.     function _getLinksUrl()
  612.     {
  613.         // Sort out query string to prevent messy urls
  614.         $querystring = array();
  615.         $qs = array();
  616.         $arrays = array();
  617.         if (!empty($_SERVER['QUERY_STRING'])) {
  618.             $qs = explode('&', str_replace('&', '&', $_SERVER['QUERY_STRING']));
  619.             for ($i = 0, $cnt = count($qs); $i < $cnt; $i++) {
  620.                 if (strstr($qs[$i], '=') !== false){ // check first if exist a pair
  621.                     list($name, $value) = explode('=', $qs[$i]);
  622.                     if ($name != $this->_urlVar) {
  623.                         //check for arrays in parameters: site.php?foo[]=1&foo[]=2&foo[]=3
  624.                         if ((strpos($name, '[') !== false) &&
  625.                             (strpos($name, ']') !== false)
  626.                         ) {
  627.                             $arrays[] = $qs[$i];
  628.                         } else {
  629.                             $qs[$name] = $value;
  630.                         }
  631.                     }
  632.                 } else {
  633.                     $qs[$qs[$i]] = '';
  634.                 }
  635.                 unset($qs[$i]);
  636.             }
  637.         }
  638.         if (is_array($this->_extraVars)) {
  639.             foreach ($this->_extraVars as $name => $value) {
  640.                 $qs[$name] = $value; //eventually overwrite duplicate vars
  641.             }
  642.         }
  643.  
  644.         foreach ($qs as $name => $value) {
  645.             $querystring[] = $name . '=' . $value;
  646.         }
  647.         $querystring = array_merge($querystring, array_unique($arrays));
  648.         $querystring = array_map('htmlspecialchars', $querystring);
  649.  
  650.         return '?' . implode('&', $querystring) . (!empty($querystring) ? '&' : '') . $this->_urlVar .'=';
  651.     }
  652.  
  653.     // }}}
  654.     // {{{ _getBackLink()
  655.  
  656.     /**
  657.      * Returns back link
  658.      *
  659.      * @param $url  URL to use in the link  [deprecated: use the factory instead]
  660.      * @param $link HTML to use as the link [deprecated: use the factory instead]
  661.      * @return string The link
  662.      * @access private
  663.      */
  664.     function _getBackLink($url='', $link='')
  665.     {
  666.         //legacy settings... the preferred way to set an option
  667.         //now is passing it to the factory
  668.         if (!empty($url)) {
  669.             $this->_path = $url;
  670.         }
  671.         if (!empty($link)) {
  672.             $this->_prevImg = $link;
  673.         }
  674.         $back = '';
  675.         if ($this->_currentPage > 1) {
  676.             $back = sprintf('<a href="%s" %s title="%s">%s</a>',
  677.                             ( $this->_append ? $this->_url.$this->getPreviousPageID() :
  678.                                     $this->_url.sprintf($this->_fileName, $this->getPreviousPageID()) ),
  679.                             $this->_classString,
  680.                             $this->_altPrev,
  681.                             $this->_prevImg)
  682.                   . $this->_spacesBefore . $this->_spacesAfter;
  683.         }
  684.         return $back;
  685.     }
  686.  
  687.     // }}}
  688.     // {{{ _getPageLinks()
  689.  
  690.     /**
  691.      * Returns pages link
  692.      *
  693.      * @param $url  URL to use in the link [deprecated: use the factory instead]
  694.      * @return string Links
  695.      * @access private
  696.      */
  697.     function _getPageLinks($url='')
  698.     {
  699.         $msg = '<b>PEAR::Pager Error:</b>'
  700.               .' function "getOffsetByPageId()" not implemented.';
  701.         return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  702.  
  703.     }
  704.  
  705.     // }}}
  706.     // {{{ _getNextLink()
  707.  
  708.     /**
  709.      * Returns next link
  710.      *
  711.      * @param $url  URL to use in the link  [deprecated: use the factory instead]
  712.      * @param $link HTML to use as the link [deprecated: use the factory instead]
  713.      * @return string The link
  714.      * @access private
  715.      */
  716.     function _getNextLink($url='', $link='')
  717.     {
  718.         //legacy settings... the preferred way to set an option
  719.         //now is passing it to the factory
  720.         if (!empty($url)) {
  721.             $this->_path = $url;
  722.         }
  723.         if (!empty($link)) {
  724.             $this->_nextImg = $link;
  725.         }
  726.         $next = '';
  727.         if ($this->_currentPage < $this->_totalPages) {
  728.             $next = $this->_spacesAfter
  729.                  . sprintf('<a href="%s" %s title="%s">%s</a>',
  730.                             ($this->_append ? $this->_url.$this->getNextPageID() :
  731.                                 $this->_url.sprintf($this->_fileName, $this->getNextPageID())),
  732.                             $this->_classString,
  733.                             $this->_altNext,
  734.                             $this->_nextImg)
  735.                  . $this->_spacesBefore . $this->_spacesAfter;
  736.         }
  737.         return $next;
  738.     }
  739.  
  740.  
  741.     // }}}
  742.     // {{{ _getPrevLinkTag()
  743.  
  744.     /**
  745.      * Returns previous link tag
  746.      *
  747.      * @return string the link tag
  748.      * @access private
  749.      */
  750.     function _getPrevLinkTag()
  751.     {
  752.         $prevLinkTag = '';
  753.         if ($this->_currentPage > 1) {
  754.             $prevLinkTag = sprintf('<link rel="previous" href="%s" title="%s" />'."\n",
  755.                                    ($this->_append ? $this->_url.$this->getPreviousPageID() :
  756.                                         $this->_url.sprintf($this->_fileName, $this->getPreviousPageID())),
  757.                                    $this->_prevLinkTitle);
  758.         }
  759.         return $prevLinkTag;
  760.     }
  761.  
  762.     // }}}
  763.     // {{{ _getNextLinkTag()
  764.  
  765.     /**
  766.      * Returns next link tag
  767.      *
  768.      * @return string the link tag
  769.      * @access private
  770.      */
  771.     function _getNextLinkTag()
  772.     {
  773.         $nextLinktag = '';
  774.         if ($this->_currentPage < $this->_totalPages) {
  775.             $nextLinktag = sprintf('<link rel="next" href="%s" title="%s" />'."\n",
  776.                                    ($this->_append ? $this->_url.$this->getNextPageID() :
  777.                                         $this->_url.sprintf($this->_fileName, $this->getNextPageID())),
  778.                                    $this->_nextLinkTitle);
  779.         }
  780.         return $nextLinktag;
  781.     }
  782.  
  783.     // }}}
  784.     // {{{ _getFirstLinkTag()
  785.  
  786.     /**
  787.      * @return string
  788.      * @access private
  789.      */
  790.     function _getFirstLinkTag()
  791.     {
  792.         if ($this->isFirstPage()) {
  793.             return '';
  794.         } else {
  795.             return sprintf('<link rel="first" href="%s" title="%s" />'."\n",
  796.                            ($this->_append ? $this->_url.'1' :
  797.                                 $this->_url.sprintf($this->_fileName, 1)),
  798.                            $this->_firstLinkTitle);
  799.         }
  800.     }
  801.  
  802.     // }}}
  803.     // {{{ _getLastLinkTag()
  804.  
  805.     /**
  806.      * @return string the link tag
  807.      * @access private
  808.      */
  809.     function _getLastLinkTag()
  810.     {
  811.         if ($this->isLastPage()) {
  812.             return '';
  813.         } else {
  814.             return sprintf('<link rel="last" href="%s" title="%s" />'."\n",
  815.                            ($this->_append ? $this->_url.$this->_totalPages :
  816.                                 $this->_url.sprintf($this->_fileName, $this->_totalPages)),
  817.                            $this->_lastLinkTitle);
  818.         }
  819.     }
  820.  
  821.     // }}}
  822.     // {{{ getPerPageSelectBox()
  823.  
  824.     /**
  825.      * Returns a string with a XHTML SELECT menu,
  826.      * useful for letting the user choose how many items per page should be
  827.      * displayed. If parameter useSessions is TRUE, this value is stored in
  828.      * a session var. The string isn't echoed right now so you can use it
  829.      * with template engines.
  830.      *
  831.      * @param integer $start
  832.      * @param integer $end
  833.      * @param integer $step
  834.      * @param boolean $showAllData If true, perPage is set equal to totalItems.
  835.      * @param array   (or string $optionText for BC reasons)
  836.      *                - 'optionText': text to show in each option.
  837.      *                  Use '%d' where you want to see the number of pages selected.
  838.      *                - 'attributes': (html attributes) Tag attributes or
  839.      *                  HTML attributes id="foo" pairs, will be inserted in the
  840.      *                  <select> tag
  841.      * @return string xhtml select box
  842.      * @access public
  843.      */
  844.     function getPerPageSelectBox($start=5, $end=30, $step=5, $showAllData=false, $extraParams=array())
  845.     {
  846.         $optionText = '%d';
  847.         $attributes = '';
  848.         if (is_string($extraParams)) {
  849.             //old behavior, BC maintained
  850.             $optionText = $extraParams;
  851.         } else {
  852.             if (array_key_exists('optionText', $extraParams)) {
  853.                 $optionText = $extraParams['optionText'];
  854.             }
  855.             if (array_key_exists('attributes', $extraParams)) {
  856.                 $attributes = $extraParams['attributes'];
  857.             }
  858.         }
  859.  
  860.         if (!strstr($optionText, '%d')) {
  861.             return ERROR_PAGER_INVALID;
  862.         }
  863.         $start = (int)$start;
  864.         $end   = (int)$end;
  865.         $step  = (int)$step;
  866.         if (!empty($_SESSION[$this->_sessionVar])) {
  867.             $selected = (int)$_SESSION[$this->_sessionVar];
  868.         } else {
  869.             $selected = $this->_perPage;
  870.         }
  871.  
  872.         $tmp = '<select name="'.$this->_sessionVar.'"';
  873.         if (!empty($attributes)) {
  874.             $tmp .= ' '.$attributes;
  875.         }
  876.         $tmp .= '>';
  877.         for ($i=$start; $i<=$end; $i+=$step) {
  878.             $tmp .= '<option value="'.$i.'"';
  879.             if ($i == $selected) {
  880.                 $tmp .= ' selected="selected"';
  881.             }
  882.             $tmp .= '>'.sprintf($optionText, $i).'</option>';
  883.         }
  884.         if ($showAllData && $end < $this->_totalItems) {
  885.             $tmp .= '<option value="'.$this->_totalItems.'"';
  886.             if ($this->_totalItems == $selected) {
  887.                 $tmp .= ' selected="selected"';
  888.             }
  889.             $tmp .= '>';
  890.             if (empty($this->_showAllText)) {
  891.                 $tmp .= sprintf($optionText, $this->_totalItems);
  892.             } else {
  893.                 $tmp .= $this->_showAllText;
  894.             }
  895.             $tmp .= '</option>';
  896.         }
  897.         $tmp .= '</select>';
  898.         return $tmp;
  899.     }
  900.  
  901.     // }}}
  902.     // {{{ _printFirstPage()
  903.  
  904.     /**
  905.      * Print [1]
  906.      *
  907.      * @return string String with link to 1st page,
  908.      *                or empty string if this is the 1st page.
  909.      * @access private
  910.      */
  911.     function _printFirstPage()
  912.     {
  913.         if ($this->isFirstPage()) {
  914.             return '';
  915.         } else {
  916.             return sprintf('<a href="%s" %s title="%s">%s%s%s</a>',
  917.                             ( $this->_append ? $this->_url.'1' : $this->_url.sprintf($this->_fileName, 1) ),
  918.                             $this->_classString,
  919.                             $this->_altPage.' 1',
  920.                             $this->_firstPagePre,
  921.                             $this->_firstPageText,
  922.                             $this->_firstPagePost)
  923.                  . $this->_spacesBefore . $this->_spacesAfter;
  924.  
  925.         }
  926.     }
  927.  
  928.     // }}}
  929.     // {{{ _printLastPage()
  930.  
  931.     /**
  932.      * Print [numPages()]
  933.      *
  934.      * @return string String with link to last page,
  935.      *                or empty string if this is the 1st page.
  936.      * @access private
  937.      */
  938.     function _printLastPage()
  939.     {
  940.         if ($this->isLastPage()) {
  941.             return '';
  942.         } else {
  943.             return sprintf('<a href="%s" %s title="%s">%s%s%s</a>',
  944.                             ( $this->_append ? $this->_url.$this->_totalPages : $this->_url.sprintf($this->_fileName, $this->_totalPages) ),
  945.                             $this->_classString,
  946.                             $this->_altPage.' '.$this->_totalPages,
  947.                             $this->_lastPagePre,
  948.                             $this->_lastPageText,
  949.                             $this->_lastPagePost);
  950.         }
  951.     }
  952.  
  953.     // }}}
  954.     // {{{ _setFirstLastText()
  955.  
  956.     /**
  957.      * sets the private _firstPageText, _lastPageText variables
  958.      * based on whether they were set in the options
  959.      *
  960.      * @access private
  961.      */
  962.     function _setFirstLastText()
  963.     {
  964.         if ($this->_firstPageText == '') {
  965.             $this->_firstPageText = '1';
  966.         }
  967.  
  968.         if ($this->_lastPageText == '') {
  969.             $this->_lastPageText = $this->_totalPages;
  970.         }
  971.     }
  972.  
  973.     // }}}
  974.     // {{{ raiseError()
  975.  
  976.     /**
  977.      * conditionally includes PEAR base class and raise an error
  978.      *
  979.      * @param string $msg  Error message
  980.      * @param int    $code Error code
  981.      * @access private
  982.      */
  983.     function raiseError($msg, $code)
  984.     {
  985.         include_once 'PEAR.php';
  986.         if (empty($this->_pearErrorMode)) {
  987.             $this->_pearErrorMode = PEAR_ERROR_RETURN;
  988.         }
  989.         PEAR::raiseError($msg, $code, $this->_pearErrorMode);
  990.     }
  991.  
  992.     // }}}
  993.     // {{{ _setOptions()
  994.  
  995.     /**
  996.      * Set and sanitize options
  997.      *
  998.      * @param mixed $options    An associative array of option names and
  999.      *                          their values.
  1000.      * @return integer error code (PAGER_OK on success)
  1001.      * @access private
  1002.      */
  1003.     function _setOptions($options)
  1004.     {
  1005.         $allowed_options = array(
  1006.             'totalItems',
  1007.             'perPage',
  1008.             'delta',
  1009.             'linkClass',
  1010.             'path',
  1011.             'fileName',
  1012.             'append',
  1013.             'urlVar',
  1014.             'altPrev',
  1015.             'altNext',
  1016.             'altPage',
  1017.             'prevImg',
  1018.             'nextImg',
  1019.             'expanded',
  1020.             'separator',
  1021.             'spacesBeforeSeparator',
  1022.             'spacesAfterSeparator',
  1023.             'curPageLinkClassName',
  1024.             'curPageSpanPre',
  1025.             'curPageSpanPost',
  1026.             'firstPagePre',
  1027.             'firstPageText',
  1028.             'firstPagePost',
  1029.             'lastPagePre',
  1030.             'lastPageText',
  1031.             'lastPagePost',
  1032.             'firstLinkTitle',
  1033.             'nextLinkTitle',
  1034.             'prevLinkTitle',
  1035.             'lastLinkTitle',
  1036.             'showAllText',
  1037.             'itemData',
  1038.             'clearIfVoid',
  1039.             'useSessions',
  1040.             'closeSession',
  1041.             'sessionVar',
  1042.             'pearErrorMode',
  1043.             'extraVars'
  1044.         );
  1045.  
  1046.         foreach ($options as $key => $value) {
  1047.             if (in_array($key, $allowed_options) && ($value !== null)) {
  1048.                 $this->{'_' . $key} = $value;
  1049.             }
  1050.         }
  1051.  
  1052.         $this->_fileName = ltrim($this->_fileName, '/');  //strip leading slash
  1053.         $this->_path     = rtrim($this->_path, '/');      //strip trailing slash
  1054.  
  1055.         if ($this->_append) {
  1056.             $this->_fileName = CURRENT_FILENAME; //avoid easy-verified user error;
  1057.             $this->_url = $this->_path.'/'.$this->_fileName.$this->_getLinksUrl();
  1058.         } else {
  1059.             $this->_url = $this->_path.'/';
  1060.             if (!strstr($this->_fileName, '%d')) {
  1061.                 return ERROR_PAGER_INVALID;
  1062.             }
  1063.         }
  1064.  
  1065.         if (strlen($this->_linkClass)) {
  1066.             $this->_classString = 'class="'.$this->_linkClass.'"';
  1067.         } else {
  1068.             $this->_classString = '';
  1069.         }
  1070.  
  1071.         if (strlen($this->_curPageLinkClassName)) {
  1072.             $this->_curPageSpanPre  = '<span class="'.$this->_curPageLinkClassName.'">';
  1073.             $this->_curPageSpanPost = '</span>';
  1074.         }
  1075.  
  1076.         if ($this->_perPage < 1) {   //avoid easy-verified user error
  1077.             $this->_perPage = 1;
  1078.         }
  1079.  
  1080.         if ($this->_useSessions && !isset($_SESSION)) {
  1081.             session_start();
  1082.         }
  1083.         if (!empty($_REQUEST[$this->_sessionVar])) {
  1084.             $this->_perPage = max(1, (int)$_REQUEST[$this->_sessionVar]);
  1085.  
  1086.             if ($this->_useSessions) {
  1087.                 $_SESSION[$this->_sessionVar] = $this->_perPage;
  1088.             }
  1089.         }
  1090.  
  1091.         if (!empty($_SESSION[$this->_sessionVar])) {
  1092.              $this->_perPage = $_SESSION[$this->_sessionVar];
  1093.         }
  1094.  
  1095.         if ($this->_closeSession) {
  1096.             session_write_close();
  1097.         }
  1098.  
  1099.         for ($i=0; $i<$this->_spacesBeforeSeparator; $i++) {
  1100.             $this->_spacesBefore .= ' ';
  1101.         }
  1102.  
  1103.         for ($i=0; $i<$this->_spacesAfterSeparator; $i++) {
  1104.             $this->_spacesAfter .= ' ';
  1105.         }
  1106.  
  1107.         if (isset($_GET[$this->_urlVar])) {
  1108.             $this->_currentPage = max((int)@$_GET[$this->_urlVar], 1);
  1109.         } else {
  1110.             $this->_currentPage = 1;
  1111.         }
  1112.  
  1113.         return PAGER_OK;
  1114.     }
  1115.  
  1116.     // }}}
  1117.     // {{{ errorMessage()
  1118.  
  1119.     /**
  1120.      * Return a textual error message for a PAGER error code
  1121.      *
  1122.      * @param   int     $code error code
  1123.      * @return  string  error message
  1124.      * @access public
  1125.      */
  1126.     function errorMessage($code)
  1127.     {
  1128.         static $errorMessages;
  1129.         if (!isset($errorMessages)) {
  1130.             $errorMessages = array(
  1131.                 ERROR_PAGER                   => 'unknown error',
  1132.                 ERROR_PAGER_INVALID           => 'invalid format - use "%d" as placeholder.',
  1133.                 ERROR_PAGER_NOT_IMPLEMENTED   => 'can not create'
  1134.             );
  1135.         }
  1136.  
  1137.         return '<b>PEAR::Pager error:</b> '. (isset($errorMessages[$code]) ?
  1138.             $errorMessages[$code] : $errorMessages[ERROR_PAGER]);
  1139.     }
  1140.  
  1141.     // }}}
  1142. }
  1143. ?>